﻿using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;

namespace Luka;

/// <summary>
/// Jwt扩展
/// </summary>
[NotScanned]
internal static class Penetrates
{
    /// <summary>
    /// 日期类型的 Claim 类型
    /// </summary>
    internal static readonly string[] DateTypeClaimTypes =
    {
        JwtRegisteredClaimNames.Iat, JwtRegisteredClaimNames.Nbf, JwtRegisteredClaimNames.Exp
    };

    /// <summary>
    /// 刷新 Token 身份标识
    /// </summary>
    internal static readonly string[] RefreshTokenClaims = { "f", "e", "s", "l", "k" };

    /// <summary>
    /// token验证参数
    /// </summary>
    internal static (TokenValidationParameters Parameters, JwtSettiing Options) GetJwtOptions()
    {
        var options = InternalApp.GetSection<JwtSettiing>("Jwt") ?? new JwtSettiing();
        return (new TokenValidationParameters
        {
            // 验证签发方密钥
            ValidateIssuerSigningKey = options.ValidateIssuerSigningKey,
            // 签发方密钥
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(options.IssuerSigningKey ?? "")),
            // 验证签发方
            ValidateIssuer = options.ValidateIssuer,
            // 设置签发方
            ValidIssuer = options.ValidIssuer,
            // 验证签收方
            ValidateAudience = options.ValidateAudience,
            // 设置接收方
            ValidAudience = options.ValidAudience,
            // 验证生存期
            ValidateLifetime = options.ValidateLifetime,
            // 过期时间容错值
            ClockSkew = TimeSpan.FromSeconds(options.ClockSkew),
        }, options);
    }

    /// <summary>
    /// 组合字典
    /// </summary>
    internal static (IDictionary<string, object> newPayload, JwtSettiing options) CombinePayload(IDictionary<string, object> payload, long? expiredTime = default)
    {
        //读取配置项
        var options = GetJwtOptions().Options;
        //添加配置项
        if (!payload.ContainsKey(JwtRegisteredClaimNames.Exp))
        {
            payload.Add(JwtRegisteredClaimNames.Exp, $"{DateTimeOffset.UtcNow.AddMinutes(expiredTime ?? options.ExpireMinutes).ToUnixTimeSeconds()}");//过期时间
        }
        if (!payload.ContainsKey(JwtRegisteredClaimNames.Iss))
        {
            payload.Add(JwtRegisteredClaimNames.Iss, options.ValidIssuer ?? "");//签发人
        }
        if (!payload.ContainsKey(JwtRegisteredClaimNames.Aud))
        {
            payload.Add(JwtRegisteredClaimNames.Aud, options.ValidAudience ?? "");//签收方
        }
        if (!payload.ContainsKey(JwtRegisteredClaimNames.Iat))
        {
            payload.Add(JwtRegisteredClaimNames.Iat, $"{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}");//签发时间
        }
        if (!payload.ContainsKey(JwtRegisteredClaimNames.Nbf))
        {
            payload.Add(JwtRegisteredClaimNames.Nbf, $"{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}");
        }
        return (payload, options);
    }
}